Tổng quan về Tập dữ liệu Chất lượng Rượu¶
- Tập dữ liệu này liên quan đến các loại rượu Vinho Verde của Bồ Đào Nha, bao gồm cả rượu vang đỏ và vang trắng (dù mô tả này chỉ đề cập chung, thường tập dữ liệu được tách làm hai file riêng biệt: red_wine và white_wine). Dữ liệu được thu thập và công bố bởi Cortez et al. (2009).
Nội dung Dữ liệu¶
Tập dữ liệu này chỉ chứa các biến lý hóa (physicochemical) và cảm quan (sensory). Do các vấn đề về bảo mật và hậu cần, không có dữ liệu về các yếu tố thương mại hay nông nghiệp như loại nho, thương hiệu rượu, hoặc giá bán.
Các Biến Đầu vào (Input Variables - Dựa trên kiểm tra lý hóa)¶
Đây là các đặc trưng được sử dụng để dự đoán chất lượng rượu:
fixed acidity: Độ axit cố định (không dễ bay hơi), chủ yếu là axit tartaric.
volatile acidity: Độ axit dễ bay hơi, chủ yếu là axit acetic (lượng cao thường cho thấy rượu bị hỏng).
citric acid: Axit citric, có thể làm tăng "độ tươi" và hương vị cho rượu.
residual sugar: Lượng đường còn lại sau khi quá trình lên men dừng lại.
chlorides: Lượng muối trong rượu.
free sulfur dioxide: Dạng SO₂ không liên kết, được thêm vào để ngăn chặn sự phát triển của vi khuẩn và quá trình oxy hóa.
total sulfur dioxide: Tổng lượng SO₂ ở dạng tự do và liên kết
density: Mật độ, có liên quan đến nồng độ cồn và lượng đường.
pH: Mức độ axit, có ảnh hưởng đến màu sắc và tiềm năng oxy hóa của rượu.
sulphates: Chất phụ gia rượu (thường ở dạng kali_sulphate) có thể góp phần vào mức SO₂ tổng thể.
Alcohol: Nồng độ cồn trong rượu.
Biến Đầu ra (Output Variable - Dựa trên dữ liệu cảm quan)
- quality: Chất lượng rượu, được đánh giá dựa trên dữ liệu cảm quan (thường là điểm trung bình từ các nhà nếm rượu chuyên nghiệp), với thang điểm từ 0 đến 10.
Tính chất của Tập dữ liệu và Ứng dụng¶
Phân loại và Hồi quy
- Tập dữ liệu này có thể được xử lý dưới dạng bài toán Phân loại (Classification) hoặc Hồi quy (Regression).
- Hồi quy: Dự đoán điểm chất lượng thực tế (từ 0 đến 10).
- Phân loại: Chuyển đổi điểm chất lượng thành các lớp nhị phân (ví dụ: "Tốt" / "Không tốt") hoặc đa lớp.
- Tập dữ liệu này có thể được xử lý dưới dạng bài toán Phân loại (Classification) hoặc Hồi quy (Regression).
Đặc điểm Quan trọng
- Lớp không cân bằng (Imbalanced Classes): Các lớp chất lượng được sắp xếp theo thứ tự, nhưng không cân bằng. Điều này có nghĩa là số lượng rượu chất lượng trung bình (ví dụ: điểm 5 hoặc 6) nhiều hơn đáng kể so với rượu chất lượng xuất sắc (ví dụ: điểm 8) hoặc kém (ví dụ: điểm 3).
Gợi ý Xử lý và Phân tích (Tips)
- Chuyển đổi sang Phân loại Nhị phân: Một gợi ý phổ biến là đặt một ngưỡng tùy ý (arbitrary cutoff) cho biến đầu ra. Ví dụ, rượu có điểm quality≥7 được phân loại là 'good/1' và phần còn lại là 'not good/0'.
- Mục tiêu Machine Learning: Mục tiêu chính là sử dụng các thuộc tính lý hóa để dự đoán hoặc xác định những yếu tố nào tạo nên một chai rượu "tốt".
- Kỹ thuật và Công cụ: Dữ liệu này rất phù hợp để thực hành các kỹ thuật như Điều chỉnh siêu tham số (Hyper parameter tuning) trên các thuật toán như Cây Quyết định (Decision Tree), đánh giá bằng đường cong ROC (Receiver Operating Characteristic) và giá trị AUC (Area Under the Curve).
import pandas as pd #for data manipulation operations
import numpy as np #for numeric operations on data
import seaborn as sns #for data visualization operations
import matplotlib.pyplot as plt #for data visualization operations
from sklearn.preprocessing import LabelEncoder # for encoding
from sklearn.preprocessing import MinMaxScaler, RobustScaler, StandardScaler #for standardization
import plotly.express as px
import plotly.graph_objects as go
import plotly.io as pio
import scipy.stats as st
#from markupsafe import escape
#!pip install pandas-profiling
#import pandas_profiling
from sklearn.model_selection import train_test_split, GridSearchCV, cross_val_score
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report
from sklearn.metrics import accuracy_score
from sklearn.metrics import roc_auc_score, roc_curve
from sklearn import model_selection
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import GradientBoostingClassifier
#!pip install lightgbm
# from lightgbm import LGBMClassifier
#ignore warnings
import warnings
warnings.filterwarnings("ignore")
#see model parametres
from sklearn import set_config
set_config(print_changed_only = False)
# Đọc file winequality-red.csv
wine_data = pd.read_csv("winequality-red.csv")
# wine_data.head(5)
wine_df = wine_data.copy()
wine_df.head(n = 10).style.background_gradient(cmap = "Purples_r")
| fixed acidity | volatile acidity | citric acid | residual sugar | chlorides | free sulfur dioxide | total sulfur dioxide | density | pH | sulphates | alcohol | quality | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 7.400000 | 0.700000 | 0.000000 | 1.900000 | 0.076000 | 11.000000 | 34.000000 | 0.997800 | 3.510000 | 0.560000 | 9.400000 | 5 |
| 1 | 7.800000 | 0.880000 | 0.000000 | 2.600000 | 0.098000 | 25.000000 | 67.000000 | 0.996800 | 3.200000 | 0.680000 | 9.800000 | 5 |
| 2 | 7.800000 | 0.760000 | 0.040000 | 2.300000 | 0.092000 | 15.000000 | 54.000000 | 0.997000 | 3.260000 | 0.650000 | 9.800000 | 5 |
| 3 | 11.200000 | 0.280000 | 0.560000 | 1.900000 | 0.075000 | 17.000000 | 60.000000 | 0.998000 | 3.160000 | 0.580000 | 9.800000 | 6 |
| 4 | 7.400000 | 0.700000 | 0.000000 | 1.900000 | 0.076000 | 11.000000 | 34.000000 | 0.997800 | 3.510000 | 0.560000 | 9.400000 | 5 |
| 5 | 7.400000 | 0.660000 | 0.000000 | 1.800000 | 0.075000 | 13.000000 | 40.000000 | 0.997800 | 3.510000 | 0.560000 | 9.400000 | 5 |
| 6 | 7.900000 | 0.600000 | 0.060000 | 1.600000 | 0.069000 | 15.000000 | 59.000000 | 0.996400 | 3.300000 | 0.460000 | 9.400000 | 5 |
| 7 | 7.300000 | 0.650000 | 0.000000 | 1.200000 | 0.065000 | 15.000000 | 21.000000 | 0.994600 | 3.390000 | 0.470000 | 10.000000 | 7 |
| 8 | 7.800000 | 0.580000 | 0.020000 | 2.000000 | 0.073000 | 9.000000 | 18.000000 | 0.996800 | 3.360000 | 0.570000 | 9.500000 | 7 |
| 9 | 7.500000 | 0.500000 | 0.360000 | 6.100000 | 0.071000 | 17.000000 | 102.000000 | 0.997800 | 3.350000 | 0.800000 | 10.500000 | 5 |
Trong đoạn mã trên, chúng ta tải tập dữ liệu. Sau đó, để phòng trường hợp cần thiết, chúng ta tạo một bản sao của tập dữ liệu, vì đôi khi có thể cần dùng đến tập dữ liệu gốc.
wine_df.shape
(1599, 12)
- Tập dữ liệu gồm 1599 hàng và 12 cột.
#Show the top rows of the dataframe
wine_data.head()
| fixed acidity | volatile acidity | citric acid | residual sugar | chlorides | free sulfur dioxide | total sulfur dioxide | density | pH | sulphates | alcohol | quality | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 7.4 | 0.70 | 0.00 | 1.9 | 0.076 | 11.0 | 34.0 | 0.9978 | 3.51 | 0.56 | 9.4 | 5 |
| 1 | 7.8 | 0.88 | 0.00 | 2.6 | 0.098 | 25.0 | 67.0 | 0.9968 | 3.20 | 0.68 | 9.8 | 5 |
| 2 | 7.8 | 0.76 | 0.04 | 2.3 | 0.092 | 15.0 | 54.0 | 0.9970 | 3.26 | 0.65 | 9.8 | 5 |
| 3 | 11.2 | 0.28 | 0.56 | 1.9 | 0.075 | 17.0 | 60.0 | 0.9980 | 3.16 | 0.58 | 9.8 | 6 |
| 4 | 7.4 | 0.70 | 0.00 | 1.9 | 0.076 | 11.0 | 34.0 | 0.9978 | 3.51 | 0.56 | 9.4 | 5 |
- Hiển thị 5 dòng đầu tiên của tập dữ liệu
# Display the last five rows of the dataframe.
wine_data.tail()
| fixed acidity | volatile acidity | citric acid | residual sugar | chlorides | free sulfur dioxide | total sulfur dioxide | density | pH | sulphates | alcohol | quality | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1594 | 6.2 | 0.600 | 0.08 | 2.0 | 0.090 | 32.0 | 44.0 | 0.99490 | 3.45 | 0.58 | 10.5 | 5 |
| 1595 | 5.9 | 0.550 | 0.10 | 2.2 | 0.062 | 39.0 | 51.0 | 0.99512 | 3.52 | 0.76 | 11.2 | 6 |
| 1596 | 6.3 | 0.510 | 0.13 | 2.3 | 0.076 | 29.0 | 40.0 | 0.99574 | 3.42 | 0.75 | 11.0 | 6 |
| 1597 | 5.9 | 0.645 | 0.12 | 2.0 | 0.075 | 32.0 | 44.0 | 0.99547 | 3.57 | 0.71 | 10.2 | 5 |
| 1598 | 6.0 | 0.310 | 0.47 | 3.6 | 0.067 | 18.0 | 42.0 | 0.99549 | 3.39 | 0.66 | 11.0 | 6 |
- Hiển thị 5 dòng dữ liệu cuối của tập dữ liệu
wine_data.columns
Index(['fixed acidity', 'volatile acidity', 'citric acid', 'residual sugar',
'chlorides', 'free sulfur dioxide', 'total sulfur dioxide', 'density',
'pH', 'sulphates', 'alcohol', 'quality'],
dtype='object')
- Số lượng cột trong tập dữ liệu
wine_df.columns = [s.strip().replace(' ', '_') for s in wine_data.columns]
wine_df.columns
Index(['fixed_acidity', 'volatile_acidity', 'citric_acid', 'residual_sugar',
'chlorides', 'free_sulfur_dioxide', 'total_sulfur_dioxide', 'density',
'pH', 'sulphates', 'alcohol', 'quality'],
dtype='object')
- Đổi tên cột (nhưng tên cột có khoảng trắng sẽ thay bằng _ )
wine_df.describe().T.style.background_gradient(cmap = "magma")
| count | mean | std | min | 25% | 50% | 75% | max | |
|---|---|---|---|---|---|---|---|---|
| fixed_acidity | 1599.000000 | 8.319637 | 1.741096 | 4.600000 | 7.100000 | 7.900000 | 9.200000 | 15.900000 |
| volatile_acidity | 1599.000000 | 0.527821 | 0.179060 | 0.120000 | 0.390000 | 0.520000 | 0.640000 | 1.580000 |
| citric_acid | 1599.000000 | 0.270976 | 0.194801 | 0.000000 | 0.090000 | 0.260000 | 0.420000 | 1.000000 |
| residual_sugar | 1599.000000 | 2.538806 | 1.409928 | 0.900000 | 1.900000 | 2.200000 | 2.600000 | 15.500000 |
| chlorides | 1599.000000 | 0.087467 | 0.047065 | 0.012000 | 0.070000 | 0.079000 | 0.090000 | 0.611000 |
| free_sulfur_dioxide | 1599.000000 | 15.874922 | 10.460157 | 1.000000 | 7.000000 | 14.000000 | 21.000000 | 72.000000 |
| total_sulfur_dioxide | 1599.000000 | 46.467792 | 32.895324 | 6.000000 | 22.000000 | 38.000000 | 62.000000 | 289.000000 |
| density | 1599.000000 | 0.996747 | 0.001887 | 0.990070 | 0.995600 | 0.996750 | 0.997835 | 1.003690 |
| pH | 1599.000000 | 3.311113 | 0.154386 | 2.740000 | 3.210000 | 3.310000 | 3.400000 | 4.010000 |
| sulphates | 1599.000000 | 0.658149 | 0.169507 | 0.330000 | 0.550000 | 0.620000 | 0.730000 | 2.000000 |
| alcohol | 1599.000000 | 10.422983 | 1.065668 | 8.400000 | 9.500000 | 10.200000 | 11.100000 | 14.900000 |
| quality | 1599.000000 | 5.636023 | 0.807569 | 3.000000 | 5.000000 | 6.000000 | 6.000000 | 8.000000 |
- Thông qua bảng phân bố như thế này ta có Nhận xét:
- Giá trị trung bình của
fixed aciditylà 8.32, giá trị cao nhất là 15.9 - Giá trị trung bình của
volatile aciditylà 0.53, giá trị cao nhất là 1.58 - Giá trị trung bình của
citric acidlà 0.27, giá trị cao nhất là 1 - Giá trị trung bình của
residual sugarlà 2.54, giá trị cao nhất là 15.5 - Giá trị trung bình của
chlorideslà 0.09, giá trị cao nhất là 0.61 - Giá trị trung bình của
free sulfur dioxidelà 15.88, giá trị cao nhất là 72 - Giá trị trung bình của
total sulfur dioxidelà 46.47, giá trị cao nhất là 289 - Giá trị trung bình của
densitylà 0.997, giá trị cao nhất là 1 - Giá trị trung bình của
pHlà 3.31, giá trị cao nhất là 4.01 - Giá trị trung bình của
sulphateslà 0.66, giá trị cao nhất là 2 - Giá trị trung bình của
alcohollà 10.42, giá trị cao nhất là 14.90 - Giá trị trung bình của
qualitylà 5.64, giá trị cao nhất là 8
- Giá trị trung bình của
wine_df.dtypes
fixed_acidity float64 volatile_acidity float64 citric_acid float64 residual_sugar float64 chlorides float64 free_sulfur_dioxide float64 total_sulfur_dioxide float64 density float64 pH float64 sulphates float64 alcohol float64 quality int64 dtype: object
- Kiểu dữ liệu của tất cả các biến đều là số.
print(wine_df.isnull().sum())
fixed_acidity 0 volatile_acidity 0 citric_acid 0 residual_sugar 0 chlorides 0 free_sulfur_dioxide 0 total_sulfur_dioxide 0 density 0 pH 0 sulphates 0 alcohol 0 quality 0 dtype: int64
- Không có bất kỳ giá trị null nào trong tập dữ liệu. Tổng số giá trị "null" trong tập dữ liệu là 0.
fig, axes = plt.subplots(1, 3, figsize = (40, 10))
sns.histplot(ax = axes[0], x = wine_df["fixed_acidity"],
bins = 10,
kde = True,
color = "#CA96EC").set(title = "Distribution of 'fixed_acidity'")
sns.histplot(ax = axes[1], x = wine_df["volatile_acidity"],
bins = 10,
kde = True,
color = "#A163CF").set(title = "Distribution of 'volatile_acidity'")
sns.histplot(ax = axes[2], x = wine_df["citric_acid"],
bins = 10,
kde = True,
color = "#29066B").set(title = "Distribution of 'citric_acid'")
plt.show()
- Nhận xét:
_Fixed acidity_: Phân bố khá giống chuẩn, tập trung nhiều quanh giá trị 7–8. Tuy nhiên hơi lệch phải nhẹ (skewed right), nghĩa là có một số rượu có độ axit cố định cao hơn mức phổ biến._Volatile acidity_: Phân bố không chuẩn, có dạng đa đỉnh (nhiều đỉnh). Phần lớn tập trung ở mức 0.4–0.6, nhưng vẫn có đỉnh phụ ở khoảng thấp hơn. Điều này cho thấy rượu có sự đa dạng rõ rệt về độ axit bay hơi._Citric acid_: Phân bố khá đặc biệt, với nhiều đỉnh rõ ràng. Giá trị bằng 0 xuất hiện nhiều (nghĩa là khá nhiều rượu không chứa axit citric). Các giá trị còn lại phân bố rải rác từ 0.1 đến 0.6, cho thấy mức độ axit citric trong rượu thay đổi mạnh.
fig, axes = plt.subplots(1, 3, figsize=(40, 10))
sns.histplot(ax = axes[0], x = wine_df["alcohol"],
bins = 10,
kde = True,
cbar = True,
color = "#641811").set(title = "Distribution of 'alcohol'");
sns.histplot(ax = axes[1], x = wine_df["residual_sugar"],
bins = 10,
kde = True,
cbar = True,
color = "#EB548C").set(title = "Distribution of 'residual_sugar'");
sns.histplot(ax = axes[2], x = wine_df["chlorides"],
bins = 10,
kde = True,
cbar = True,
color = "#EC96E0").set(title = "Distribution of 'chlorides'");
plt.show()
- Nhận xét:
_Alcohol_: Phân bố lệch phải rõ rệt (right-skewed). Phần lớn mẫu tập trung ở mức 9–11 độ cồn. Một số ít rượu có độ cồn cao hơn (tới gần 15), nhưng khá hiếm.- -> Điều này cho thấy đa số rượu có nồng độ cồn trung bình, rượu có độ cồn cao là ngoại lệ.
_Residual sugar_: Phân bố lệch phải mạnh. Phần lớn mẫu tập trung quanh mức 2–3 g/L, số lượng giảm nhanh khi đường dư cao hơn. Có vài ngoại lệ (outliers) với giá trị đường dư lên tới 10–15 g/L, nhưng cực kỳ ít.- -> Điều này phản ánh đa số rượu không ngọt nhiều, chỉ một số nhỏ có lượng đường cao.
_Chlorides_: Phân bố cũng lệch phải rất mạnh. Hầu hết giá trị tập trung quanh mức 0.07–0.1. Một số ít ngoại lệ có giá trị cao tới 0.5–0.6.- -> Nhìn chung, đa phần rượu có lượng muối thấp, chỉ vài mẫu vượt trội hẳn.
sns.pairplot(wine_df, diag_kind = "hist", hue = "quality", height = 3, aspect = 1.2, corner = True);
plt.show()
- Nhận xét:
Phân phối các biến (ô chéo chính):
- Nhiều biến không tuân theo phân phối chuẩn (ví dụ
residual_sugar,chlorides,sulphatesbị lệch phải). - Một số biến có phân phối gần chuẩn hơn như
fixed_acidity,citric_acid,alcohol.
- Nhiều biến không tuân theo phân phối chuẩn (ví dụ
Quan hệ giữa các biến (ô ngoài chéo):
Alcoholvàquality: có xu hướng dương – rượu có nồng độ cồn cao thì chất lượng thường tốt hơn.Volatile acidityvàquality: có xu hướng âm – độ chua bay hơi cao thì chất lượng giảm.Citric acidvàquality: hơi dương – nhiều acid citric có thể liên quan đến chất lượng cao hơn.
Một số biến có mối quan hệ khá rõ rệt với nhau:
densitytỉ lệ thuận vớiresidual_sugarvàfixed_acidity.pHcó quan hệ nghịch vớifixed_acidity.
Các cặp biến gần như không có quan hệ:
- Ví dụ
alcoholvàchlorides,pHvàalcohol— các điểm phân tán rất rời rạc, không theo quy luật rõ ràng.
- Ví dụ
# Include information about values
corr = wine_data.corr()
fig, ax = plt.subplots()
fig.set_size_inches(14, 8)
sns.heatmap(corr, annot=True, fmt=".1f", cmap="RdBu", center=0, ax=ax)
plt.show()
- Nhận xét từ heatmap tương quan:
Quan hệ mạnh giữa các biến:
fixed_acidity↔density(0.7): độ acid cố định càng cao thì mật độ rượu càng lớn.fixed_acidity↔citric_acid(0.7): rượu có nhiều acid cố định thì thường cũng có nhiều acid citric.free_sulfur_dioxide↔total_sulfur_dioxide(0.7): hợp lý vì tổng SO₂ bao gồm SO₂ tự do.
Quan hệ nghịch mạnh:
fixed_acidity↔pH(-0.7): acid càng cao thì pH càng thấp (hợp lý về mặt hóa học).density↔alcohol(-0.5): rượu có nồng độ cồn cao thì mật độ thấp hơn.
Các biến liên quan đến chất lượng (quality):
alcoholcó tương quan dương tương đối mạnh (0.5) → rượu có nhiều cồn thì thường được đánh giá chất lượng cao hơn.volatile_aciditycó tương quan âm (-0.4) → acid bay hơi nhiều làm giảm chất lượng rượu.citric_acidcó tương quan dương nhẹ (0.2) → acid citric góp phần tăng chất lượng.- Các biến khác (
residual_sugar,chlorides,SO₂,density) hầu như không ảnh hưởng đáng kể.
Ý nghĩa tổng quát:
- Không phải tất cả biến đều ảnh hưởng đến chất lượng rượu.
- Ba biến quan trọng nhất để dự đoán chất lượng:
alcohol,volatile_acidity,citric_acid.
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
axes = axes.flatten()
sns.scatterplot(ax = axes[0],
x = "residual_sugar",
y = "quality", hue = "quality",
data = wine_df).set(title = "Relationship between 'residual_sugar' and 'quality'");
sns.scatterplot(ax = axes[1],
x = "alcohol",
y = "quality", hue = "quality",
data = wine_df).set(title = "Relationship between 'alcohol' and 'quality'");
sns.scatterplot(ax = axes[2],
x = "pH",
y = "quality", hue = "quality",
data = wine_df).set(title = "Relationship between 'pH' and 'quality'");
sns.scatterplot(ax = axes[3],
x = "density",
y = "quality", hue = "quality",
data = wine_df).set(title = "Relationship between 'density' and 'quality'");
plt.show()
Nhận xét:
Residual SugarvsQuality
- Phần lớn rượu có lượng residual sugar thấp (≤ 5).
- Không có sự khác biệt rõ rệt về residual sugar giữa các mức chất lượng (3–8).
-> Residual sugar không ảnh hưởng mạnh đến quality.
AlcoholvsQuality
- Có xu hướng: rượu có alcohol cao hơn (≥ 11) thường đạt quality cao hơn (6–8).
- Rượu có alcohol thấp (≈ 9–10) tập trung nhiều ở chất lượng thấp (3–5).
-> Alcohol có mối quan hệ tích cực với quality.
pHvsQuality
- Phần lớn rượu có pH tập trung quanh 3.1 – 3.4.
- Không có sự khác biệt rõ ràng giữa các nhóm quality theo pH.
-> pH không phải yếu tố chính ảnh hưởng đến quality.
DensityvsQuality
- Density tập trung mạnh trong khoảng 0.995 – 1.000.
- Có xu hướng rượu chất lượng cao (7–8) thường nằm ở mức density thấp hơn một chút.
-> Density có thể liên quan ngược chiều với quality (density thấp → chất lượng tốt hơn).
sns.scatterplot(x = "residual_sugar",
y = "pH",
hue = "quality",
data = wine_df).set(title = "Relationship between 'residual_sugar' and 'pH'");
- Nhận xét:
Phân bố dữ liệu:
- Phần lớn điểm dữ liệu tập trung ở residual_sugar từ 1–5 và pH khoảng 3.0–3.5.
- Một số ít rượu có lượng đường dư cao (>10), nhưng đó là ngoại lệ, chiếm tỷ lệ rất nhỏ.
Mối quan hệ giữa
residual_sugarvàpH- Không thấy mối quan hệ tuyến tính rõ ràng (tức là residual_sugar tăng không đồng nghĩa pH tăng hay giảm theo quy luật).
- Dữ liệu khá phân tán, nhưng đa phần tập trung thành “cụm dày” ở vùng
residual_sugarthấp và pH trung bình (3.0–3.4).
Theo chất lượng (quality)
- Các điểm thuộc mọi mức chất lượng (3–8) đều xuất hiện trong vùng tập trung chính → tức là chỉ dựa vào
residual_sugarvàpHthì khó phân biệt rõ rệt các nhóm chất lượng rượu. - Tuy nhiên, rượu chất lượng cao (7–8, màu đậm hơn) dường như cũng tập trung nhiều ở vùng
residual_sugarthấp (khoảng 2–3) vàpHtừ 3.1–3.4.
- Các điểm thuộc mọi mức chất lượng (3–8) đều xuất hiện trong vùng tập trung chính → tức là chỉ dựa vào
sns.scatterplot(x = "alcohol",
y = "pH",
hue = "quality",
palette = "magma",
data = wine_df).set(title = "Relationship between 'alcohol' and 'pH'");
- Nhận xét:
Phân bố dữ liệu:
- Dữ liệu tập trung chủ yếu trong khoảng
alcoholtừ 9–12 vàpHtừ 3.0–3.4. - Một số ít rượu có nồng độ cồn cao (>13) nhưng không nhiều, chủ yếu thuộc nhóm chất lượng khá/tốt.
- Dữ liệu tập trung chủ yếu trong khoảng
Mối quan hệ giữa
alcoholvàpH- Có xu hướng cùng tăng nhẹ: khi
alcoholtăng,pHcó xu hướng cao hơn một chút, nhưng quan hệ này không mạnh. - Các điểm vẫn phân tán, không tạo thành đường rõ ràng.
- Có xu hướng cùng tăng nhẹ: khi
Theo chất lượng (quality)
- Rượu chất lượng thấp (3–4) xuất hiện nhiều ở vùng
alcoholthấp (8–10). - Rượu chất lượng cao (7–8) xuất hiện nhiều hơn ở vùng
alcoholcao (≥11),pHthường quanh 3.2–3.4. - Điều này gợi ý rằng nồng độ cồn cao có liên quan đến chất lượng rượu tốt hơn, trong khi
pHkhông phải yếu tố quyết định mạnh.
- Rượu chất lượng thấp (3–4) xuất hiện nhiều ở vùng
fig, axes = plt.subplots(nrows = 4, ncols = 3, figsize = (20, 20))
colors = ['#491D8B', '#6929C4', '#8A3FFC', '#A56EFF',
'#7D3AC1', '#AF4BCE', '#DB4CB2', '#EB548C',
'#EC96E0', '#A2128E', '#E8D9F3', '#641811']
for index, column in enumerate(wine_df.columns):
ax = axes.flatten()[index]
ax.hist(wine_df[column], color = colors[index], label = column)
ax.legend(loc = "best")
plt.suptitle("Histograms", size = 18)
plt.show()
- Nhận xét:
Fixed Acidity:- Phân bố lệch phải nhẹ (right-skewed).
- Chủ yếu dao động từ 6–10, tập trung khoảng 7–8.
Volatile Acidity:- Phân bố hơi lệch phải, phần lớn giá trị từ 0.3–0.7.
- Có vài trường hợp ngoại lai (outliers) trên 1.
Citric Acid:- Phân bố khá phân tán, không đều, nhiều “đỉnh nhỏ” (multi-modal).
- Nhiều mẫu có citric acid = 0 (không chứa).
Residual Sugar:- Rất lệch phải, phần lớn giá trị < 3.
- Một số ít trường hợp có giá trị rất cao (~10–15), có thể là ngoại lai.
Chlorides:- Lệch phải rõ rệt, hầu hết < 0.15.
- Một vài ngoại lai với giá trị > 0.4.
Free Sulfur Dioxide:- Phân bố lệch phải, tập trung khoảng 5–35.
- Có mẫu cực cao (~70).
Total Sulfur Dioxide:- Lệch phải mạnh, đa số nằm trong khoảng 20–150.
- Một số giá trị ngoại lai > 200.
Density:- Phân bố gần chuẩn (normal-like), tập trung mạnh trong khoảng 0.994–0.998.
pH:- Phân bố gần chuẩn, tập trung quanh 3.2–3.4.
Sulphates:- Lệch phải nhẹ, tập trung quanh 0.5–0.7.
- Có vài điểm cao > 1.5 (outliers).
Alcohol:- Lệch phải, đa số nằm trong khoảng 9–11.
- Một số rượu có độ cồn cao (12–14).
Quality:- Phân bố rời rạc (categorical-like).
- Phần lớn rượu có chất lượng 5–6 (chiếm nhiều nhất).
- Ít rượu chất lượng thấp (3–4) hoặc cao (7–8).
dataForPlot = wine_df.groupby('quality').mean().total_sulfur_dioxide
fig, ax = plt.subplots()
ax.bar(dataForPlot.index, dataForPlot, color=['C0','C1','C3','C4','C5','C6'])
ax.set_xticks([3, 4, 5, 6, 7, 8])
ax.set_xlabel('Quality')
ax.set_ylabel('Avg. Total Sulfur Dioxide')
plt.show()
- Nhận xét:
- Rượu có chất lượng 5 có tổng lượng
sulfur dioxidetrung bình cao nhất (~57). → Cho thấy
sulfur dioxidecó xu hướng nhiều nhất ở mức chất lượng trung bình.- Chất lượng thấp (3, 4) có
sulfur dioxidethấp hơn so với mức 5, nhưng vẫn tăng dần từ 3 → 4 → 5. - Chất lượng cao (6, 7, 8) lại có mức
sulfur dioxidetrung bình thấp hơn, giảm dần so với 5. - Từ mức 6 trở đi,
sulfur dioxidegiảm xuống khoảng 35–40. - Xu hướng tổng thể:
Sulfur dioxidecao nhất ở rượu chất lượng trung bình (5).- Rượu chất lượng cao (7–8) có xu hướng ít
sulfur dioxidehơn → có thể liên quan đến chất lượng cảm quan (sulfur dioxidecao thường ảnh hưởng vị và mùi).
- Rượu có chất lượng 5 có tổng lượng
dataForPlot = wine_df.groupby('quality').mean().residual_sugar
fig, ax = plt.subplots()
ax.bar(dataForPlot.index, dataForPlot, color=['C0'])
ax.set_xticks([3, 4, 5, 6, 7, 8])
ax.set_xlabel('Quality')
ax.set_ylabel('Avg. Residual Sugar')
plt.show()
- Nhận xét:
- Giá trị trung bình của
Residual Sugardao động trong khoảng ~2.5–2.7, tức là không có sự chênh lệch quá lớn giữa các mức chất lượng. - Rượu chất lượng 4 và 7 có lượng đường dư trung bình cao nhất (~2.7).
- Đặc biệt, mức 7 (chất lượng cao) vẫn giữ đường dư tương đối nhiều.
- Rượu chất lượng 6 có lượng đường dư trung bình thấp nhất (~2.48).
- Không thấy xu hướng tuyến tính rõ ràng (ví dụ: không phải đường dư càng thấp thì rượu càng ngon).
- Giá trị trung bình của
wine_df.plot.scatter(x='fixed_acidity', y='pH', legend=False)
plt.show()
- Nhận xét:
Mối quan hệ nghịch rõ rệt:
- Khi
fixed aciditytăng, thì pH giảm. - Điều này hợp lý về mặt hóa học: độ axit cao hơn thì pH thấp hơn.
- Khi
Phân bố dữ liệu tập trung nhiều nhất:
fixed_aciditynằm trong khoảng 6–10.pHnằm trong khoảng 3.0–3.5.
Một số giá trị ngoại lai (outliers):
- Ở mức
fixed_acidity> 13 hoặc < 5 có ít điểm dữ liệu. - Tương tự, có một số rượu có pH gần 4.0 hoặc dưới 2.9, hiếm gặp.
- Ở mức
Quan hệ gần tuyến tính nghịch:
- Đường xu hướng có thể được mô tả bằng hồi quy tuyến tính âm.
- Biểu đồ này là một bước kiểm tra dữ liệu quan trọng, xác nhận rằng các biến số liên quan đến độ axit trong tập dữ liệu đang hoạt động theo đúng nguyên tắc hóa học. Nó cho thấy mối tương quan nghịch mạnh mẽ giữa Độ Chua Cố Định và pH.
dataForPlot = wine_df.groupby('quality').mean().free_sulfur_dioxide
fig, ax = plt.subplots()
ax.bar(dataForPlot.index, dataForPlot, color=['C0'])
ax.set_xticks([3, 4, 5, 6, 7, 8])
ax.set_xlabel('Quality')
ax.set_ylabel('Avg. of free_sulfur_dioxide')
plt.show()
- Nhận xét:
Xu hướng chung:
- Hàm lượng free sulfur dioxide tăng dần khi chất lượng rượu từ 3 → 5.
- Đạt mức cao nhất ở chất lượng 5 (~17).
Sau đó có xu hướng giảm:
- Từ chất lượng 6 → 8, giá trị trung bình free sulfur dioxide giảm dần (~15 → 13).
Ý nghĩa:
- Lượng free sulfur dioxide (SO₂ tự do) vừa phải có thể góp phần bảo quản rượu và giữ hương vị, nhưng quá nhiều hay quá ít đều không đảm bảo chất lượng tối ưu.
- Chất lượng trung bình (5–6) lại có mức SO₂ cao nhất, trong khi rượu chất lượng cao hơn (7–8) có xu hướng ít SO₂ hơn, có thể do quá trình sản xuất tinh chỉnh hơn, ít phụ thuộc vào chất bảo quản.
- biểu đồ này cho thấy SO2 Tự do đạt đỉnh ở chất lượng Q=5 và có mối quan hệ nghịch với chất lượng cao hơn (Q=6,7,8). Điều này gợi ý rằng lượng SO2 Tự do quá cao thường là đặc điểm của rượu vang chất lượng trung bình/thấp.
plt.boxplot([wine_df['free_sulfur_dioxide'], wine_df['total_sulfur_dioxide']], vert=False)
plt.xlabel('Sulphur Dioxide')
plt.ylabel('Wine Quality')
plt.title('Free vs Total Sulphur Dioxide in Wine')
plt.yticks([1, 2], ['Free', 'Total'])
plt.show()
- Nhận xét:
Tổng thể:
Total Sulphur Dioxide(SO₂ tổng) có giá trị lớn hơn rất nhiều so vớiFree Sulphur Dioxide(SO₂ tự do).- Điều này hợp lý vì SO₂ tổng bao gồm cả SO₂ tự do + SO₂ liên kết.
Phân bố:
Free Sulphur Dioxide:- Median (trung vị) khoảng ~15.
- Phần lớn dữ liệu nằm trong khoảng 10 – 25.
- Có một số outlier (giá trị ngoại lệ) trên 50.
Total Sulphur Dioxide:- Median cao hơn, khoảng ~35.
- Phần lớn dữ liệu tập trung 20 – 60.
- Có nhiều outlier rất lớn, thậm chí trên 200 – 300, cho thấy một số mẫu rượu có sử dụng lượng SO₂ tổng cực kỳ cao.
So sánh mức độ biến động:
Total SO₂có biến thiên rộng hơn nhiều so vớiFree SO₂.Free SO₂tương đối ổn định, ít giá trị ngoại lệ hơn.
- biểu đồ này trực quan hóa một cách hiệu quả sự khác biệt về quy mô và phân bố giữa hai dạng SO2, nhấn mạnh rằng SO2 Tổng cộng có giá trị trung vị, phạm vi và các giá trị cực đoan cao hơn nhiều.
# Calculate the sum of density and sum of residual sugar for each row
wine_df['sum_density_residual_sugar'] = wine_df['density'] + wine_df['residual_sugar']
# Create a scatter plot with quality as the color of each point
plt.scatter(wine_df['quality'],wine_df['sum_density_residual_sugar'], c=wine_df['quality'])
plt.xlabel('Sum of Density and Residual Sugar')
plt.ylabel('Quality')
plt.colorbar()
plt.show()
- Nhận xét:
Trục X: Tổng mật độ và đường dư (density + residual_sugar).
Trục Y: Chất lượng rượu (quality).
Màu sắc: Phân biệt các mức chất lượng (từ 3 → 8).
Phân bố dữ liệu:
- Giá trị tổng
density + residual_sugarchủ yếu nằm trong khoảng 3 đến 8. - Ở mức chất lượng thấp (3, 4, 5), giá trị này trải khá đều, không có sự khác biệt rõ rệt so với chất lượng cao hơn.
- Giá trị tổng
Xu hướng chất lượng:
- Không thấy có mối quan hệ tuyến tính rõ ràng giữa density + residual_sugar và quality.
- Các mức chất lượng khác nhau bị chồng lấn mạnh (cùng một giá trị tổng có nhiều chất lượng khác nhau).
- Ví dụ: tại giá trị ~5–6, ta có cả rượu chất lượng 3, 4, 5, 6, 7, 8.
Kết luận sơ bộ:
- Biến
density + residual_sugarkhông phải là một đặc trưng mạnh để phân biệt chất lượng rượu. - Tuy nhiên, nó vẫn có thể hữu ích nếu kết hợp với các biến khác (alcohol, pH, sulfur dioxide...) trong mô hình dự đoán.
- Nếu dùng riêng biến này để phân loại chất lượng, kết quả sẽ khá yếu vì dữ liệu bị chồng lấn nhiều.
- Biến
sns.histplot(data=wine_df, x=wine_df.fixed_acidity, hue="quality", kde=True, bins=20, multiple="stack", alpha=.3)
plt.show()
- Nhận xét:
Trục X: Độ axit cố định (
fixed_acidity), với giá trị trải từ khoảng 5 đến 16.Trục Y: Số lượng mẫu (Count) tương ứng với mỗi khoảng giá trị
fixed_acidity.Màu sắc: Phân biệt các mức chất lượng rượu (quality) từ 3 đến 8.
Phân bố dữ liệu:
- Phân bố chung của
fixed_acidity: Tổng số lượng mẫu (khi cộng tất cả các màu) tập trung chủ yếu trong khoảng 6.5 đến 9.0, đạt đỉnh tại khoảng 7.5. - Phân bố theo Chất lượng (quality):
- Các mức chất lượng trung bình (như quality=5 và quality=6) chiếm số lượng mẫu áp đảo và có sự phân bố rộng nhất, đỉnh của chúng nằm trong khoảng fixed_acidity tập trung (khoảng 7.0 đến 8.0).
- Các mức chất lượng thấp (quality=3,4) và cao (quality=7,8) có số lượng mẫu rất ít so với quality=5,6.
- Chất lượng cao nhất (quality=8) có phân bố trải rộng nhưng số lượng mẫu rất ít, với đỉnh phân bố tập trung rõ rệt quanh 7.5 và một lượng nhỏ trải đến 10-11.
- Chất lượng thấp nhất (quality=3) và (quality=4) cũng có phân bố tương tự, nhưng chủ yếu nằm trong khoảng 6.0 đến 9.0.
- Phân bố chung của
Xu hướng chất lượng:
- Chồng lấn mạnh mẽ: Biểu đồ cho thấy sự chồng lấn rất lớn giữa các mức chất lượng (quality) trên toàn bộ phạm vi giá trị
fixed_acidity. Cụ thể, trong khoảng giá trịfixed_acidityphổ biến nhất (khoảng 6.5 đến 9.0), ta tìm thấy mẫu của tất cả các mức chất lượng từ 3 đến 8. - Không có mối quan hệ đơn điệu rõ ràng: Không thấy có mối quan hệ tuyến tính hay phi tuyến tính mạnh và đơn điệu giữa
fixed_acidityvàquality(ví dụ:fixed_aciditycàng cao thìqualitycàng cao/thấp). Các mức chất lượng cao và thấp đều có xu hướng tập trung ở mức độ axit cố định trung bình.
- Chồng lấn mạnh mẽ: Biểu đồ cho thấy sự chồng lấn rất lớn giữa các mức chất lượng (quality) trên toàn bộ phạm vi giá trị
def quality(variables):
plt.figure(figsize=(16, 5))
sns.histplot(data=wine_data, x=variables, hue="quality", kde=True,bins=20)
if quality == "density": plt.title(f"\n{variables} of red wine\n\n")
else: plt.title(f"\n{variables} contents in red wine\n\n")
plt.figtext(0.75, 0.3, f'{wine_data[variables].describe()}')
sns.despine()
quality("fixed_acidity")
plt.show
<function matplotlib.pyplot.show(close=None, block=None)>
Nhận xét:
Phân bố chung của Độ Axit Cố định (fixed_acidity)
Thống kê Mô tả (fixed_acidity)
- Số lượng mẫu (count): 1599 mẫu.
- Giá trị trung bình (mean): Khoảng 8.32.
- Độ lệch chuẩn (std): Khoảng 1.74.
- Phân vị (Quartiles): 50% dữ liệu nằm trong khoảng 7.10 (25%) đến 9.20 (75%).
- Khoảng giá trị: Từ 4.60 (min) đến 15.90 (max).
Hình dạng Phân bố
- Phân bố tổng thể (fixed_acidity) có dạng lệch phải nhẹ (do mean≈8.32 lớn hơn median=7.90) và tập trung mạnh mẽ trong khoảng 6.5 đến 9.5.
Phân bố theo Chất lượng Rượu (quality)
- Sự Tập trung Dữ liệu
- Chất lượng Trung bình (quality=5,6): Hai mức chất lượng này chiếm phần lớn số lượng mẫu (được thể hiện qua chiều cao của các histogram và KDE). Phân bố của chúng gần như là phân bố chung, với đỉnh tập trung mạnh mẽ trong khoảng 7.0 đến 8.5.
- Chất lượng Cao và Thấp: Các mức chất lượng cực đoan (quality=3,4,7,8) có số lượng mẫu ít hơn đáng kể (thanh histogram thấp hơn) so với quality=5 và quality=6.
- Sự Tập trung Dữ liệu
Mối quan hệ fixed_acidity và quality
- Chồng lấn (Overlap): Đây là nhận xét quan trọng nhất. Biểu đồ cho thấy sự chồng lấn rất lớn giữa các mức chất lượng. Tại hầu hết các giá trị fixed_acidity phổ biến (đặc biệt là từ 6.0 đến 11.0), ta có thể tìm thấy mẫu rượu thuộc nhiều mức chất lượng khác nhau (từ 4 đến 7 hoặc 8).
- Không có Xu hướng Rõ ràng: Không thấy có mối quan hệ đơn điệu (tăng hoặc giảm đều đặn) rõ ràng giữa fixed_acidity và quality. Cả rượu chất lượng cao (quality=7,8) và chất lượng thấp (quality=4) đều có phân bố tập trung mạnh nhất ở các mức fixed_acidity trung bình (khoảng 7.0 đến 9.0).
Kết luận Sơ bộ:
- Đặc trưng Yếu: Biến fixed_acidity không phải là một đặc trưng phân loại chất lượng rượu mạnh khi xét độc lập, vì nó không đủ để tách biệt các nhóm chất lượng do hiện tượng chồng lấn dữ liệu rộng.
- Vai trò Tiềm năng: Để dự đoán chất lượng rượu hiệu quả, fixed_acidity cần được kết hợp với các biến hóa học khác (như pH, citric_acid, alcohol,...) để xây dựng một mô hình dự đoán đa biến.
#bar chart of average quantity ordered per country
dataForPlot = wine_data.groupby('quality').mean().residual_sugar
fig, ax = plt.subplots()
ax.barh(dataForPlot.index, dataForPlot, color=['C5', 'C1'])
ax.set_xticklabels(dataForPlot.index, rotation=90)
ax.set_xlabel('Avg. of Residual Sugar')
ax.set_ylabel('Quality')
plt.show()
- Nhận xét:
Phân bố Giá trị
- Giá trị Trung bình của Đường dư nằm trong khoảng tương đối hẹp, chủ yếu từ khoảng 7.9 đến 8.5 cho tất cả các mức chất lượng.
- Giá trị thấp nhất thuộc về Quality=8 (khoảng 8.1).
- Giá trị cao nhất thuộc về Quality=4 (khoảng 8.4) và Quality=7 (khoảng 8.5).
Xu hướng Chất lượng
- Không có mối quan hệ rõ ràng: Biểu đồ cho thấy không có mối quan hệ tuyến tính (Linear Relationship) hay xu hướng tăng/giảm rõ ràng giữa Quality và Avg. of Residual Sugar.
- Rượu chất lượng thấp (Quality=3 và 4) và rượu chất lượng cao (Quality=7) đều có Avg. of Residual Sugar tương đối cao (khoảng 8.3 đến 8.5).
- Rượu chất lượng trung bình (Quality=5,6) có giá trị Avg. of Residual Sugar nằm ở mức thấp hơn một chút (khoảng 8.1 đến 8.2).
- Sự khác biệt không đáng kể: Mặc dù có sự khác biệt nhỏ về chiều dài thanh, sự khác biệt này (chỉ khoảng 0.4 đơn vị trên trục X) là rất nhỏ và khó có thể coi Residual Sugar là yếu tố phân biệt mạnh cho chất lượng rượu khi xét độc lập.
- Không có mối quan hệ rõ ràng: Biểu đồ cho thấy không có mối quan hệ tuyến tính (Linear Relationship) hay xu hướng tăng/giảm rõ ràng giữa Quality và Avg. of Residual Sugar.
Kết luận Sơ bộ
- Biến Lượng đường dư (Residual Sugar) dường như không phải là yếu tố quyết định chính đến chất lượng rượu. Các mức chất lượng khác nhau có lượng đường dư trung bình gần như giống nhau.
- Điều này gợi ý rằng Residual Sugar có thể không đóng góp nhiều vào việc phân loại chất lượng rượu trong mô hình dự đoán, hoặc ảnh hưởng của nó bị chi phối bởi các yếu tố hóa học khác (như alcohol, pH, volatile_acidity).
fig, ax = plt.subplots()
ax.hist(wine_data.density)
ax.set_axisbelow(True) # Show the grid lines behind the histogram
ax.grid(which='major', color='grey', linestyle='--')
ax.set_xlabel('density')
ax.set_ylabel('count')
plt.show()
- Nhận xét:
Dạng Phân bố
- Hình dạng: Phân bố của density có dạng gần đối xứng và trông gần giống phân bố Chuẩn (Normal Distribution).
- Đỉnh (Mode): Phân bố đạt đỉnh cao nhất (tần số lớn nhất, count gần 500) tại khoảng giá trị density từ 0.996 đến 0.998 (cụ thể là thanh histogram cao nhất).
Sự Tập trung và Khoảng biến thiên
- Sự Tập trung: Phần lớn các mẫu dữ liệu (hơn 75%) tập trung rất mạnh mẽ trong khoảng density từ 0.994 đến 1.000.
- Khoảng biến thiên: Giá trị density trải rộng từ khoảng 0.990 đến 1.004.
- Giá trị Trung bình: Giá trị trung bình của density nằm đâu đó trong khoảng 0.996 đến 0.998 do tính đối xứng của phân bố.
Kết luận Sơ bộ
- Biến density có sự phân bố rất tập trung xung quanh một giá trị trung bình hẹp.
- Điều này gợi ý rằng, trong tập dữ liệu này (thường là dữ liệu về rượu vang), density là một đặc trưng khá ổn định và không có nhiều sự biến động lớn giữa các mẫu rượu.
# Add the correlation coefficient to the scatterplots above the diagonal
from pandas.plotting import scatter_matrix, parallel_coordinates
df = wine_data[['volatile_acidity', 'sulphates', 'alcohol']]
axes = scatter_matrix(df, alpha=0.5, figsize=(6, 6), diagonal='kde') #kde is for density plots, you can use "hist" for histogram
corr = df.corr().values
for i, j in zip(*plt.np.triu_indices_from(axes, k=1)):
axes[i, j].annotate("%.3f" %corr[i,j], (0.8, 0.8), xycoords='axes fraction', ha='center', va='center')
plt.show()
- Nhận xét:
Phân bố Từng Biến (Đường chéo)
- Phần đường chéo của ma trận hiển thị Biểu đồ ước lượng mật độ nhân (KDE - Kernel Density Estimate) cho từng biến:
- volatile_acidity (Độ axit dễ bay hơi): Phân bố lệch phải mạnh. Đa số các mẫu có độ axit dễ bay hơi thấp, với đỉnh mật độ nằm dưới 0.5.
- sulphates: Phân bố cũng lệch phải, tập trung cao tại mức sulphates khoảng 0.6 đến 0.8.
- alcohol (Nồng độ cồn): Phân bố có dạng gần đối xứng hơn, có xu hướng béo ở đuôi phải hoặc có hai đỉnh (bimodal), tập trung chủ yếu trong khoảng 9.5 đến 12.5.
- Phần đường chéo của ma trận hiển thị Biểu đồ ước lượng mật độ nhân (KDE - Kernel Density Estimate) cho từng biến:
Mối quan hệ giữa các Biến (Biểu đồ Tán xạ)
Các biểu đồ ngoài đường chéo thể hiện mối quan hệ giữa hai biến, kèm theo hệ số tương quan Pearson (r) được hiển thị ở góc trên bên phải của biểu đồ tán xạ tương ứng (phần tam giác trên):
A. volatile_acidity vs sulphates
- Hệ số tương quan (r=−0.261): Cho thấy mối quan hệ tương quan nghịch yếu (hoặc rất yếu).
- Biểu đồ tán xạ: Các điểm dữ liệu phân tán rộng. Tuy nhiên, có một xu hướng mờ nhạt: khi volatile_acidity tăng, sulphates có xu hướng giảm nhẹ.
B. volatile_acidity vs alcohol
- Hệ số tương quan (r=−0.202): Cho thấy mối quan hệ tương quan nghịch rất yếu.
- Biểu đồ tán xạ: Các điểm dữ liệu rất phân tán. Không có mối quan hệ tuyến tính rõ ràng. Tuy nhiên, dữ liệu có vẻ trải rộng hơn ở mức alcohol cao hơn, và alcohol cao nhất thường đi kèm với volatile_acidity thấp.
C. sulphates vs alcohol
- Hệ số tương quan (r=0.094): Cho thấy mối quan hệ tương quan thuận cực kỳ yếu (gần như không có tương quan tuyến tính).
- Biểu đồ tán xạ: Các điểm dữ liệu phân tán hoàn toàn ngẫu nhiên và không tạo thành bất kỳ hình dạng hay xu hướng nào.
Kết luận Tổng thể
- Trong ba cặp biến được phân tích, không có cặp biến nào có mối quan hệ tuyến tính mạnh mẽ. Tất cả các hệ số tương quan đều rất gần 0 (từ −0.261 đến 0.094).
- Cặp biến có mối quan hệ tuyến tính rõ ràng nhất (dù vẫn yếu) là volatile_acidity và sulphates (r≈−0.261).
- Cặp sulphates và alcohol hầu như độc lập với nhau về mặt tuyến tính (r≈0.094).
fig, axes = plt.subplots(nrows=1, ncols=3)
wine_data.boxplot(column='alcohol', by='quality', ax=axes[0])
wine_data.boxplot(column='volatile_acidity', by='quality', ax=axes[1])
wine_data.boxplot(column='sulphates', by='quality', ax=axes[2])
for ax in axes:
ax.set_xlabel('quality')
plt.suptitle('') # Suppress the overall title
plt.tight_layout() # Increase the separation between the plots
plt.show()
- Nhận xét:
Nồng độ Cồn (alcohol)
- Xu hướng Rõ rệt: Có một mối quan hệ thuận (tương quan dương) rõ ràng giữa quality và alcohol.
- Khi quality tăng từ 3 lên 8, giá trị trung vị (đường kẻ ngang bên trong hộp) và toàn bộ hộp (IQR) của alcohol có xu hướng dịch chuyển lên cao hơn.
- Ví dụ: Rượu quality=3 và 4 có trung vị thấp (khoảng 9.8 và 10.0), trong khi quality=8 có trung vị cao nhất (khoảng 12.5).
- Phân biệt Chất lượng: alcohol là một đặc trưng mạnh để phân biệt giữa các mức chất lượng, đặc biệt giữa nhóm chất lượng thấp/trung bình (3, 4, 5) và nhóm chất lượng cao (7, 8).
- Ngoại lệ (Outliers): Có nhiều giá trị ngoại lệ ở hầu hết các mức chất lượng, đặc biệt là ở quality=5.
- Xu hướng Rõ rệt: Có một mối quan hệ thuận (tương quan dương) rõ ràng giữa quality và alcohol.
Độ Axit Dễ Bay hơi (volatile_acidity)
- Xu hướng Rõ rệt: Có một mối quan hệ nghịch (tương quan âm) rõ ràng giữa quality và volatile_acidity.
- Khi quality tăng từ 3 lên 8, giá trị trung vị và hộp (IQR) của volatile_acidity có xu hướng dịch chuyển xuống thấp hơn.
- Ví dụ: Rượu quality=3 có trung vị cao nhất (khoảng 0.85), trong khi quality=8 có trung vị thấp nhất (khoảng 0.37).
- Phân biệt Chất lượng: volatile_acidity là một đặc trưng mạnh để phân biệt chất lượng. Độ axit dễ bay hơi thấp thường gắn liền với chất lượng cao hơn.
- Ngoại lệ (Outliers): Có nhiều giá trị ngoại lệ (cao) ở các mức chất lượng trung bình (4, 5, 6).
- Xu hướng Rõ rệt: Có một mối quan hệ nghịch (tương quan âm) rõ ràng giữa quality và volatile_acidity.
Sulphates (sulphates)
- Xu hướng Yếu: Mối quan hệ giữa quality và sulphates không rõ ràng như hai biến trên, nhưng có xu hướng thuận nhẹ:
- Giá trị trung vị và hộp cho quality=7 và quality=8 có vẻ cao hơn một chút so với các mức chất lượng thấp hơn (3, 4).
- Trung vị của quality=3 và 4 thấp (khoảng 0.53), còn quality=7 và 8 cao hơn (khoảng 0.75).
- Đặc điểm Nổi bật: Sự phân bố của sulphates bị chồng lấn rất nhiều giữa các mức chất lượng. Sự khác biệt giữa các hộp là không đáng kể.
- Ngoại lệ (Outliers): Biến này có rất nhiều giá trị ngoại lệ cao ở tất cả các mức chất lượng, đặc biệt là quality=5.
- Xu hướng Yếu: Mối quan hệ giữa quality và sulphates không rõ ràng như hai biến trên, nhưng có xu hướng thuận nhẹ:
Kết luận Tổng thể
- Các đặc trưng Quan trọng: alcohol (tương quan thuận) và volatile_acidity (tương quan nghịch) là hai đặc trưng hóa học quan trọng nhất để phân biệt chất lượng rượu.
- Đặc trưng Yếu: sulphates có mối quan hệ yếu hơn và phân bố bị chồng lấn nhiều hơn, nhưng vẫn có vai trò trong việc cải thiện chất lượng ở các mức cao hơn.